#include "stdafx.h"
#include "Value.h"

using namespace pb::cfg;

namespace {

    const int          kSizeLength = 2;
    const unsigned int kMaxLength  = 0xFFFF;

    bool loadLength(std::fstream& in, unsigned int& length)
    {
        return true;
    }

    void saveLength(std::fstream& out, const unsigned int length)
    {
        if (   length > 0 
            && length < kMaxLength)
        {
            unsigned int temp = length;

            char buffer[kSizeLength];
            for (int i = kSizeLength - 1; i >= 0; --i)
            {
                buffer[i] = (char)(temp & 0xFF);
                temp = temp >> 8;
            }

            out.write(buffer, kSizeLength);
        }
    }

    bool loadStr(std::fstream& in, std::string& str)
    {
        return true;
    }

    void saveStr(std::fstream& out, const std::string& str)
    {
        out.write(str.data(), str.size());
    }

    bool loadType(std::fstream& in, char& type)
    {
        return true;
    }

    void saveType(std::fstream& out, char type)
    {
        out.write(&type, 1);
    }
}

Value::Value(Config* cfg, const std::string& name, const EType type)
    : m_cfg(cfg)
    , m_lengthOfName(0)
    , m_type(type)
    , m_lengthOfData(0)
{
    assert(cfg);

    if (lengthOfName(name.size()))
        m_name = name;
}

Value::~Value()
{
}

void
Value::save(std::fstream& out)
{
    if (valid())
    {
        ::saveLength(out, m_lengthOfName);
        ::saveStr(out, m_name);
        ::saveType(out, (char)m_type);
        ::saveLength(out, m_lengthOfData);
        saveData(out);
    }
}

bool
Value::lengthOfName(const unsigned int length)
{
    if (length < kMaxLength)
    {
        m_lengthOfName = length;
        return true;
    }
    
    m_lengthOfName = 0;
    return true;
}

bool
Value::lengthOfData(const unsigned int length)
{
    if (length < kMaxLength)
    {
        m_lengthOfData = length;
        return true;
    }
    
    m_lengthOfData = 0;
    return false;
}

bool
Value::valid() const
{
    return (   m_lengthOfName > 0
            && m_lengthOfData > 0);
}

Value::EType
Value::type() const
{
    return m_type;
}